/**
 * Redis 客户端（基础设施层）
 */
const Redis = require('ioredis');
const { getLogger } = require('../logger');
const logger = getLogger('infra.redisClient');
const config = require('../../config');

const redisCfg = config.redis || {};

let redisClient = null;
let isConnected = false;
let lastHealthCheckTime = 0;
const HEALTH_CHECK_INTERVAL = 30000;

const isRedisEnabled = () => {
  return Boolean(redisCfg && redisCfg.host && redisCfg.port);
};

const initializeRedisClient = () => {
  if (!redisClient && isRedisEnabled()) {
    try {
      redisClient = new Redis(redisCfg);
      redisClient.on('connect', () => {
        isConnected = true;
        logger.info('Redis连接成功');
      });
      redisClient.on('ready', () => {
        isConnected = true;
        logger.info('Redis客户端准备就绪');
      });
      redisClient.on('error', (err) => {
        if (isConnected) {
          logger.error('Redis连接错误:', { error: err.message });
        }
        isConnected = false;
      });
      redisClient.on('close', () => {
        if (isConnected) {
          logger.warn('Redis连接已关闭');
        }
        isConnected = false;
      });
      redisClient.on('reconnecting', (info) => {
        const attempt = info?.attempt || '?';
        const delay = info?.delay || '?';
        logger.info(`Redis正在重新连接 (尝试 ${attempt} / ${delay}ms)`);
      });
    } catch (error) {
      logger.error('创建Redis客户端失败:', { error: error });
    }
  }
  return redisClient;
};

const getRedisClient = () => {
  if (!redisClient && isRedisEnabled()) {
    initializeRedisClient();
  }
  return redisClient;
};

const isRedisConnected = () => isConnected;

const checkConnection = async () => {
  if (!redisClient || !isRedisEnabled()) {
    return false;
  }
  const now = Date.now();
  if (now - lastHealthCheckTime < HEALTH_CHECK_INTERVAL) {
    return isConnected;
  }
  lastHealthCheckTime = now;
  try {
    if (redisClient.status !== 'connecting' && redisClient.status !== 'connected') {
      logger.warn(`Redis连接状态异常: ${redisClient.status}`);
      isConnected = false;
      return false;
    }
    await redisClient.ping();
    isConnected = true;
    return true;
  } catch (error) {
    if (isConnected) {
      logger.warn('Redis连接检查失败:', { error: error });
    }
    isConnected = false;
    return false;
  }
};

const performHealthCheck = async () => {
  if (!redisClient || !isRedisEnabled()) {
    logger.debug('Redis未启用，跳过健康检查');
    return false;
  }
  const now = Date.now();
  if (now - lastHealthCheckTime < HEALTH_CHECK_INTERVAL) {
    return isConnected;
  }
  lastHealthCheckTime = now;
  try {
    const wasConnected = isConnected;
    const response = await redisClient.ping();
    if (response === 'PONG') {
      isConnected = true;
      if (!wasConnected) {
        logger.info('✅ Redis连接恢复');
      } else {
        logger.debug('✅ Redis连接正常');
      }
      return true;
    }
    logger.warn('❌ Redis健康检查失败: 意外响应');
    isConnected = false;
    return false;
  } catch (error) {
    if (isConnected) {
      logger.warn('❌ Redis健康检查失败，请检查Redis服务状态:', { error: error });
    }
    isConnected = false;
    return false;
  }
};

const closeConnection = async () => {
  try {
    if (redisClient) {
      isConnected = false;
      redisClient.removeAllListeners();
      await redisClient.quit();
      logger.info('Redis连接已优雅关闭');
    }
  } catch (error) {
    logger.error('关闭Redis连接时出错:', { error: error });
  }
};

module.exports = {
  initializeRedisClient,
  getRedisClient,
  performHealthCheck,
  isRedisConnected,
  checkConnection,
  closeConnection,
  isRedisEnabled
};